﻿using System;
using System.Threading;
using Affinity.Core.Collections;

namespace Affinity.Core.Utility
{
    public static class Threading
    {
        // Set this to an action that marshals calls to the UI thread.
        public static Action<Action> ExecuteOnUIThreadImplementation { get; set; }

        /*
        public static void ExecuteOnUIThreadAfterDelay(TimeSpan delay, Action action)
        {
            Threading.ExecuteOnUIThread(() =>
                {
                    DispatcherTimer timer = new DispatcherTimer();
                    timer.Interval = delay;
                    timer.Tick += (sender, e) =>
                        {
                            timer.Stop();
                            _ActiveTimers.Remove(timer);
                            action();
                        };

                    _ActiveTimers.Add(timer);
                    timer.Start();
                });
        }
        */

        public static void ExecuteOnUIThread(Action action)
        {
            ExecuteOnUIThread(false, action);
        }

        public static void ExecuteOnUIThread(bool alwaysDispatch, Action action)
        {
            if (action == null) throw new ArgumentNullException("action");

            if (ExecuteOnUIThreadImplementation == null) action();
            else ExecuteOnUIThreadImplementation(action);

            /*
            // If we're in design mode, cross our fingers: if we're not on the UI thread, we can't access the UI thread's dispatcher without getting an exception.
            if (DesignerProperties.IsInDesignTool) action();
            else if (alwaysDispatch || !UIThreadDispatcher.CheckAccess()) UIThreadDispatcher.BeginInvoke(action);
            else action();
             */
        }

        public static void ExecuteOnUIThreadAndAwaitCompletion(Action action)
        {
            if (action == null) throw new ArgumentNullException("action");

            using (ManualResetEvent completionSignal = new ManualResetEvent(false))
            {
                ExecuteOnUIThread(() =>
                {
                    action();
                    completionSignal.Set();
                });

                completionSignal.WaitOne();
            }
        }

        /*
        public static bool ExecuteOnBackgroundWorkerThread(Action action)
        {
            return ThreadPool.QueueUserWorkItem(state => action());
        }

        public static bool ExecuteOnBackgroundWorkerThreadAndHandleResultOnUIThread<TResult>(Func<TResult> func, Action<TResult> callback)
        {
            return ThreadPool.QueueUserWorkItem(state =>
            {
                TResult result = func();
                ExecuteOnUIThread(() => callback(result));
            });
        }

        public static bool ExecuteOnBackgroundWorkerThreadAndHandleResultOnUIThread<TResult, TState>(Func<TResult> func, Action<TResult, TState> callback, TState userState)
        {
            return ThreadPool.QueueUserWorkItem(state =>
            {
                TResult result = func();
                ExecuteOnUIThread(() => callback(result, userState));
            });
        }
        */

        /*
        private static Dispatcher UIThreadDispatcher
        {
            get { return Deployment.Current.Dispatcher; }
        }

        private static readonly SynchronizedList<DispatcherTimer> _ActiveTimers = new SynchronizedList<DispatcherTimer>();
    
         */
    }
}
